import asyncio
from tornado import web
import json
import pymysql
from transformers import BertForSequenceClassification
from transformers import BertTokenizer
import torch
import time
import requests
import datetime
import re


def to_json(data): # 包装JSON类型的数据
    return json.dumps(data, ensure_ascii=False)

class BaseHandler(web.RequestHandler):
    def set_default_headers(self):
        # 设置跨域请求头和content-type
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET')
        self.set_header('Access-Control-Max-Age', 1000)
        self.set_header('Access-Control-Allow-Headers', '*')
        self.set_header('Content-type', 'application/json')

class MainHandler(BaseHandler):
    def get(self): # 响应get类型的请求
        name = self.get_query_argument("name")
        age = self.get_query_argument("age")
        # 获取GET请求参数
        print(name, type(name), age, type(age))

        # @TODO 服务的具体逻辑写在这个地方，这个print是个示例
        print('OK')

        self.write('Hello World')

class PostDemoHandler(BaseHandler):
    def post(self):
        data = self.request.body.decode('utf-8')
        # 获取POST请求的body参数
        print(data)

        ret = {
            'status': True,
            'code': 1,
            'msg': 'success',
        }
        self.write(to_json(ret))

class PostSentimentHandler(BaseHandler):
    def format_str(self,text):
        text = re.sub(r"(回复)?(//)?\s*@\S*?\s*(:| |$)", " ", text)  # 去除正文中的@和回复/转发中的用户名
        text = re.sub(r"\[\S+\]", "", text)  # 去除表情符号
        text = re.sub(r"【\S+】", "", text)  # 去除保留话题内容
        text = re.sub(r"#\S+#", "", text)  # 去除保留话题内容
        URL_REGEX = re.compile(
            r'(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))',
            re.IGNORECASE)
        text = re.sub(URL_REGEX, "", text)  # 去除网址
        text = text.replace("转发微博", "")  # 去除无意义的词语
        text = re.sub(r"\s+", " ", text)  # 合并正文中过多的空格
        return text.strip()

    def translate_tozh(self, basic_str, langid):
        url = "http://10.119.130.188:8517/multi_translate"
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
        }
        data = {
            "src_lang": langid,
            "tgt_lang": "ch",
            "src_content": basic_str
        }

        response = requests.post(url=url, json=data, headers=headers)
        return response.text

    def post(self):

        data = self.request.body.decode('utf-8')
        # 获取POST请求的body参数


        json_data = json.loads(data)

        # Now you can access values from the parsed JSON data
        basic_str = self.format_str(json_data.get('text'))
        lang = json_data.get('lang')
        S = 0

        try:
            Langid = lang
            if (Langid == 'zang'):  # 藏语
                basic_str = self.translate_tozh(basic_str, 'zang')
            elif (Langid == 'meng'):  # 蒙语
                basic_str = self.translate_tozh(basic_str, 'meng')
            elif (Langid == 'wei'):  # 维
                basic_str = self.translate_tozh(basic_str, 'wei')
            elif (Langid == 'en'):
                basic_str = self.translate_tozh(basic_str, 'en')
            print(basic_str)
            output = model2(torch.tensor([tokenizer2.encode(basic_str)]).to(device))
            A = torch.nn.functional.softmax(output.logits, dim=-1)[0][0].item()
            print(A)
        except:
            A = 0.5
            print("异常")
        sen = 0
        if (basic_str == ""):
            S = 1
        if A > 0.90:
            sen = 2
        elif A <= 0.95 and A >= 0.3:
            sen = 1
        else:
            sen = 3

        if (S == 1): sen = 1

        print(sen)
        s=""
        if(sen==1):s="中性"
        elif(sen==2):s="负向"
        elif(sen==3):s="正向"







        ret = {
            'status': True,
            'code': 1,
            'msg': sen,
            'message':s
        }
        self.write(to_json(ret))

class TestHandler(BaseHandler):
    def get(self):
        # 由于test接口不需要额外的逻辑，所以这里啥也不用写

        ret = {
            'status': True,
        }

        self.write(to_json(ret)) # 返回JSON格式的数据

def make_app():
    return web.Application([
        (r'/', MainHandler), # 设置url路径，绑定具体处理业务逻辑的类
        (r'/test', TestHandler), # 绑定测试服务运行状态逻辑

        ##  实际应用中把示例删除即可
        (r'/start_sentiment_analysis', PostDemoHandler), #POST请求示例
        (r'/sentiment_analysis/save', PostSentimentHandler)  # POST请求示例
        # 其他接口继续在这下边定义..
    ])

async def main():

    PORT = 8898 # 端口，同一台服务器上，不同服务端口要不一样
    app = make_app()
    app.listen(PORT)
    print('> service is running on port: %d' % PORT)



    await asyncio.Event().wait()


if __name__ == '__main__':
    print("正在加载模型")
    tokenizer2 = BertTokenizer.from_pretrained('IDEA-CCNL/Erlangshen-Roberta-110M-Sentiment')
    model2 = BertForSequenceClassification.from_pretrained('IDEA-CCNL/Erlangshen-Roberta-110M-Sentiment')
    device = torch.device('cuda:1' if torch.cuda.is_available() else 'cpu')
    model2.to(device)
    print("模型加载完成")

    asyncio.run(main())